﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;

namespace ImageRecognition2
{
    /// <summary>
    /// 
    /// </summary>
    public delegate void BinaryCcodedEventHandler(object sender, CodeEventArgs e);

    /// <summary>
    /// Binary coded eventargs
    /// </summary>
    public class CodeEventArgs
    {
        public event BinaryCcodedEventHandler binaryCodedEvent = null;

        private string m_sFileName = string.Empty;
        private bool m_bSuccess = false;

        /// <summary>
        /// Initializes a new instance of the <see cref="CodeEventArgs"/> class.
        /// </summary>
        /// <param name="_sFileName">Name of the _s file.</param>
        /// <param name="_bSuccess">if set to <c>true</c> [_b success].</param>
        public CodeEventArgs(string _sFileName, bool _bSuccess)
        {
            m_sFileName = _sFileName;
            m_bSuccess = _bSuccess;
        }

        /// <summary>
        /// Gets the name of the file.
        /// </summary>
        /// <value>The name of the file.</value>
        public string FileName
        {
            get { return m_sFileName; }
        }

        /// <summary>
        /// Gets a value indicating whether this <see cref="CodeEventArgs"/> is success.
        /// </summary>
        /// <value><c>true</c> if success; otherwise, <c>false</c>.</value>
        public bool Success
        {
            get { return m_bSuccess; }
        }
    }

    /// <summary>
    /// Binary Coder
    /// </summary>
    public class BinaryCoder
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="BinaryCoder"/> class.
        /// </summary>
        public BinaryCoder()
        {
        }

        /// <summary>
        /// Codes the specified _s file name.
        /// </summary>
        /// <param name="_sFileName">Name of the _s file.</param>
        /// <returns></returns>
        public bool Code(string _sFileName)
        {
            bool bSuccess = false;
            if (!_sFileName.EndsWith("_coded"))
            {
                BinaryReader reader = new BinaryReader(new FileStream(_sFileName, FileMode.Open));

                FileInfo fileInfo = new FileInfo(_sFileName);

                byte[] aByte = reader.ReadBytes((int)fileInfo.Length);
                reader.Close();

                ReverseByteArray(aByte);

                BinaryWriter writer = new BinaryWriter(new FileStream(_sFileName + "_coded", FileMode.Create));
                writer.Write(aByte);
                writer.Close();
                bSuccess = true;
            }
            else
            {
                bSuccess = false;
            }
            OnCoded(new CodeEventArgs(_sFileName, bSuccess));
            return bSuccess;
        }

        /// <summary>
        /// Reads the decoded.
        /// </summary>
        /// <param name="_sFileName">Name of the _s file.</param>
        /// <returns></returns>
        public byte[] ReadDecoded(string _sFileName)
        {
            byte[] aByte = null;
            FileInfo fileInfo = new FileInfo(_sFileName);
            if (_sFileName.EndsWith("_coded"))
            {
                BinaryReader reader = new BinaryReader(new FileStream(_sFileName, FileMode.Open));
                aByte = reader.ReadBytes((int)fileInfo.Length);
                reader.Close();

                ReverseByteArray(aByte);
            }
            return aByte;
        }

        /// <summary>
        /// Reads the specified _s file name.
        /// </summary>
        /// <param name="_sFileName">Name of the _s file.</param>
        /// <returns></returns>
        public byte[] Read(string _sFileName)
        {
            FileInfo fileInfo = new FileInfo(_sFileName);
            BinaryReader reader = new BinaryReader(new FileStream(_sFileName, FileMode.Open));
            byte[] aByte = new byte[fileInfo.Length];
            reader.ReadBytes((int)fileInfo.Length);
            reader.Close();
            return aByte;
        }

        /// <summary>
        /// Reverses the byte array.
        /// </summary>
        /// <param name="aByte">A byte.</param>
        private void ReverseByteArray(byte[] aByte)
        {
            for (int i = 0; i < aByte.Length; i++)
            {
                aByte[i] = (byte)(255 - aByte[i]);
            }
        }

        /// <summary>
        /// Gets as image.
        /// </summary>
        /// <param name="_sFileName">Name of the _s file.</param>
        /// <returns></returns>
        public Image GetAsImage(string _sFileName)
        {
            byte[] aByte = ReadDecoded(_sFileName);

            MemoryStream stream = new MemoryStream(aByte);
            Image image = Image.FromStream(stream);
            return image;
        }

        /// <summary>
        /// Batches the code.
        /// </summary>
        /// <param name="_sPath">The _s path.</param>
        /// <returns></returns>
        public bool BatchCode(string _sPath)
        {
            if (!Directory.Exists(_sPath))
            {
                return false;
            }

            bool bSuccess = true;
            foreach (string _sFile in Directory.GetFiles(_sPath))
            {
                bool bCoded = Code(_sFile);
                string sText = string.Format("{0} codiert: {1} ", _sFile, bCoded ? "erfolgreich" : "fehler");
                bSuccess &= bCoded;
            }
            return bSuccess;
        }

        /// <summary>
        /// Raises the <see cref="E:Coded"/> event.
        /// </summary>
        /// <param name="e">The <see cref="ImageRecognition2.CodeEventArgs"/> instance containing the event data.</param>
        public void OnCoded(CodeEventArgs e)
        {
            //if (m_B != null)
            {
                //BinaryDecodedEvent(this, e);
            }
        }
    }
}
